package com.suncky.frame.utils;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.suncky.frame.AppConfig;

import java.io.Serializable;

public class ToastUtils {
    private static final int MESSAGE_TOAST = 1001;
    private static final int MESSAGE_TOAST_LONG = 1002;
    private static final int MESSAGE_TOAST_VIEW = 1003;
    private static final int MESSAGE_TOAST_LONG_VIEW = 1004;

    private static class HandlerHolder {
        private static final Handler HANDLER = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                switch (getWhat(msg)) {
                    case MESSAGE_TOAST:
                        showToast(msg, Toast.LENGTH_SHORT);
                        break;
                    case MESSAGE_TOAST_LONG:
                        showToast(msg, Toast.LENGTH_LONG);
                        break;
                    case MESSAGE_TOAST_VIEW:
                        showToastWithCustomView(msg, Toast.LENGTH_SHORT);
                        break;
                    case MESSAGE_TOAST_LONG_VIEW:
                        showToastWithCustomView(msg, Toast.LENGTH_LONG);
                        break;
                    default:
                        break;
                }
            }
        };
    }

    private static Handler getHandler() {
        return HandlerHolder.HANDLER;
    }

    public static void post(Runnable run) {
        getHandler().post(run);
    }

    public static void postDelayed(Runnable run, long delayMillis) {
        getHandler().postDelayed(run, delayMillis);
    }

    public static void cancel(Runnable r) {
        getHandler().removeCallbacks(r);
    }

    public static void toast(int res) {
        toast(res, null);
    }

    public static void toast(int res, View.OnAttachStateChangeListener listener) {
        toast(AppConfig.getAppContext().getString(res), listener);
    }

    public static void toast(String message) {
        toast(message, null);
    }

    public static void toast(String message, View.OnAttachStateChangeListener listener) {
        MessageInfo info = new MessageInfo();
        info.message = message;
        info.listener = listener;
        getHandler().obtainMessage(MESSAGE_TOAST, info).sendToTarget();
    }

    public static void toastLong(int res) {
        toastLong(res, null);
    }

    public static void toastLong(int res, View.OnAttachStateChangeListener listener) {
        toastLong(AppConfig.getAppContext().getString(res), listener);
    }

    public static void toastLong(String message) {
        toastLong(message, null);
    }

    public static void toastLong(String message, View.OnAttachStateChangeListener listener) {
        MessageInfo info = new MessageInfo();
        info.message = message;
        info.listener = listener;
        getHandler().obtainMessage(MESSAGE_TOAST_LONG, info).sendToTarget();
    }

    public static void toastCustomView(View view, int gravity, int xOffset, int yOffset) {
        toastCustomView(view, gravity, xOffset, yOffset, null);
    }

    public static void toastCustomView(View view, int gravity, int xOffset, int yOffset, View.OnAttachStateChangeListener listener) {
        ViewInfo info = new ViewInfo();
        info.view = view;
        info.gravity = gravity;
        info.xOffset = xOffset;
        info.yOffset = yOffset;
        info.listener = listener;
        getHandler().obtainMessage(MESSAGE_TOAST_VIEW, info).sendToTarget();
    }

    public static void toastCustomViewLong(View view, int gravity, int xOffset, int yOffset) {
        toastCustomViewLong(view, gravity, xOffset, yOffset, null);
    }

    public static void toastCustomViewLong(View view, int gravity, int xOffset, int yOffset, View.OnAttachStateChangeListener listener) {
        ViewInfo info = new ViewInfo();
        info.view = view;
        info.gravity = gravity;
        info.xOffset = xOffset;
        info.yOffset = yOffset;
        info.listener = listener;
        getHandler().obtainMessage(MESSAGE_TOAST_LONG_VIEW, info).sendToTarget();
    }

    private static void showToast(Message msg, int duration) {
        if (msg == null) {
            return;
        }
        Object o = msg.obj;
        if (o == null || !(o instanceof MessageInfo)) {
            return;
        }
        final String message = ((MessageInfo) o).message;
        if (TextUtils.isEmpty(message) || TextUtils.isEmpty(message.trim())) {
            return;
        }
        final Toast toast = Toast.makeText(AppConfig.getAppContext(), message, duration);
        if (toast == null) {
            return;
        }
        final View view = toast.getView(); //理论上不会出现null，为嘛小米手机上会出现？
        final View.OnAttachStateChangeListener attachStateChangeListener = ((MessageInfo) o).listener;
        if (attachStateChangeListener != null && view != null) {
            view.addOnAttachStateChangeListener(attachStateChangeListener);
        }
        toast.show();
    }

    private static void showToastWithCustomView(Message msg, int duration) {
        if (msg == null) {
            return;
        }
        Object o = msg.obj;
        if (o == null || !(o instanceof ViewInfo)) {
            return;
        }
        View view = ((ViewInfo) o).view;
        if (view == null) {
            return;
        }
        final Toast toast = new Toast(AppConfig.getAppContext());
        final View.OnAttachStateChangeListener attachStateChangeListener = ((ViewInfo) o).listener;
        if (attachStateChangeListener != null) {
            view.addOnAttachStateChangeListener(attachStateChangeListener);
        }
        toast.setView(view);
        toast.setGravity(((ViewInfo) o).gravity, ((ViewInfo) o).xOffset, ((ViewInfo) o).yOffset);
        toast.setDuration(duration);
        toast.show();
    }

    private static int getWhat(Message msg) {
        if (msg == null) {
            return 0;
        }
        return msg.what;
    }

    private static class ViewInfo implements Serializable {
        View view;
        View.OnAttachStateChangeListener listener;
        int gravity;
        int xOffset;
        int yOffset;
    }

    private static class MessageInfo implements Serializable {
        String message;
        View.OnAttachStateChangeListener listener;
    }
}
